---
sidebar_label: Custom functions
sidebar_position: 6
description: Manage custom functions with the Hasura Metadata API
keywords:
  - hasura
  - docs
  - Metadata API
  - API reference
  - custom function
---

# Metadata API Reference: Custom Functions

## Introduction

Track/untrack a custom SQL function in the Hasura GraphQL Engine.

Only tracked custom functions are available for
querying/mutating/subscribing data over the GraphQL API.

:::tip Supported from

The Metadata API is supported for versions `v2.0.0` and above and
replaces the older [schema/Metadata API](/api-reference/schema-metadata-api/index.mdx).

:::

## pg_track_function {#metadata-pg-track-function}

`pg_track_function` is used to add a custom SQL function to the GraphQL
schema. It supports more configuration options than v1, and also
supports tracking custom functions as mutations. Also refer a note
[here](/api-reference/syntax-defs.mdx#function-req-note).

Track an SQL function called `search_articles` with a Hasura session argument:

```http
POST /v1/metadata HTTP/1.1
Content-Type: application/json
X-Hasura-Role: admin

{
    "type": "pg_track_function",
    "args": {
        "source": "default",
        "function": {
            "schema": "public",
            "name": "search_articles"
        },
        "configuration": {
            "session_argument": "hasura_session"
        },
        "comment": "This function helps search for articles"
    }
}
```

Track `VOLATILE` SQL function `reset_widget` as a mutation, so it
appears as a top-level field under the `mutation` root field:

```http
POST /v1/metadata HTTP/1.1
Content-Type: application/json
X-Hasura-Role: admin

{
    "type": "pg_track_function",
    "args": {
        "function": {
            "schema": "public",
            "name": "reset_widget"
        },
        "configuration": {
            "exposed_as": "mutation"
        },
        "source": "default"
    }
}
```

If `exposed_as` is omitted, the location in the schema to expose the
function will be inferred from the function's volatility, with
`VOLATILE` functions appearing under the `mutation` root, and others
ending up under `query/subscription`.

In most cases you will want `VOLATILE` functions to only be exposed as
mutations, and only `STABLE` and `IMMUTABLE` functions to be queries.
When tracking `VOLATILE` functions under the `query` root, the user
needs to guarantee that the field is idempotent and side-effect free, in
the context of the resulting GraphQL API.

One such use case might be a function that wraps a simple query and
performs some logging visible only to administrators.

:::info Note

It's easy to accidentally give an SQL function the wrong volatility (or
for a function to end up with `VOLATILE` mistakenly, since it's the
default).

:::

### Args syntax {#metadata-pg-track-function-syntax}

| Key           | Required | Schema                                                                          | Description                                                                                                                   |
| ------------- | -------- | ------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------- |
| function      | true     | [FunctionName](/api-reference/syntax-defs.mdx#functionname)                     | Name of the SQL function                                                                                                      |
| configuration | false    | [Function Configuration](/api-reference/syntax-defs.mdx#function-configuration) | Configuration for the SQL function                                                                                            |
| source        | false    | [SourceName](/api-reference/syntax-defs.mdx#sourcename)                         | Name of the source database of the function (default: `default`)                                                              |
| comment       | false    | String                                                                          | Comment for the function. This comment would replace the auto-generated comment for the function field in the GraphQL schema. |

## pg_untrack_function {#metadata-pg-untrack-function}

`pg_untrack_function` is used to remove a SQL function from the GraphQL schema.

Remove an SQL function `search_articles`:

```http
POST /v1/metadata HTTP/1.1
Content-Type: application/json
X-Hasura-Role: admin

{
    "type": "pg_untrack_function",
    "args": {
        "function": {
           "schema": "public",
           "name": "search_articles"
        },
        "source": "default"
    }
}
```

### Args syntax {#metadata-pg-untrack-function-syntax}

| Key      | Required | Schema                                                      | Description                                                      |
| -------- | -------- | ----------------------------------------------------------- | ---------------------------------------------------------------- |
| function | true     | [FunctionName](/api-reference/syntax-defs.mdx#functionname) | Name of the SQL function                                         |
| source   | false    | [SourceName](/api-reference/syntax-defs.mdx#sourcename)     | Name of the source database of the function (default: `default`) |

## pg_set_function_customization {#metadata-pg-set-function-customization}

`pg_set_function_customization` allows you to customize any given
function with a custom name and custom root fields of an already tracked
function. This will **replace** the already present customization.

Set the configuration for a function called `search_articles`:

```http
POST /v1/metadata HTTP/1.1
Content-Type: application/json
X-Hasura-Role: admin

{
   "type": "pg_set_function_customization",
   "args": {
     "function": "search_articles",
     "source": "default",
     "configuration": {
       "custom_root_fields": {
         "function": "FindArticles",
         "function_aggregate": "FindArticlesAgg"
       }
     }
   }
}
```

### Args syntax {#metadata-pg-set-function-customization-syntax}

| Key           | Required | Schema                                                                          | Description                                                      |
| ------------- | -------- | ------------------------------------------------------------------------------- | ---------------------------------------------------------------- |
| function      | true     | [FunctionName](/api-reference/syntax-defs.mdx#functionname)                     | Name of the function                                             |
| configuration | false    | [Function Configuration](/api-reference/syntax-defs.mdx#function-configuration) | Configuration for the function                                   |
| source        | false    | [SourceName](/api-reference/syntax-defs.mdx#sourcename)                         | Name of the source database of the function (default: `default`) |

## pg_create_function_permission {#metadata-pg-create-function-permission}

`pg_create_function_permission` is used to add permission to an existing
custom function. To add a function permission, the provided role should
have select permissions to the target table of the function.

```http
POST /v1/metadata HTTP/1.1
Content-Type: application/json
X-Hasura-Role: admin

{
    "type": "pg_create_function_permission",
    "args": {
       "function": "get_articles",
       "source": "default",
       "role": "user"
    }
}
```

### Args syntax {#metadata-pg-create-function-permission-syntax}

| Key      | Required | Schema                                                      | Description                                                      |
| -------- | -------- | ----------------------------------------------------------- | ---------------------------------------------------------------- |
| function | true     | [FunctionName](/api-reference/syntax-defs.mdx#functionname) | Name of the SQL function                                         |
| role     | true     | [RoleName](/api-reference/syntax-defs.mdx#rolename)         | Name of the role                                                 |
| source   | false    | Text                                                        | Name of the source database of the function (default: `default`) |

## pg_drop_function_permission {#metadata-pg-drop-function-permission}

`pg_drop_function_permission` is used to drop an existing function permission.

```http
POST /v1/metadata HTTP/1.1
Content-Type: application/json
X-Hasura-Role: admin

{
    "type": "pg_drop_function_permission",
    "args": {
       "function": "get_articles",
       "role": "user",
       "source": "default"
    }
}
```

### Args syntax {#metadata-pg-drop-function-permission-syntax}

| Key      | Required | Schema                                                      | Description                                                      |
| -------- | -------- | ----------------------------------------------------------- | ---------------------------------------------------------------- |
| function | true     | [FunctionName](/api-reference/syntax-defs.mdx#functionname) | Name of the SQL function                                         |
| role     | true     | [RoleName](/api-reference/syntax-defs.mdx#rolename)         | Name of the role                                                 |
| source   | false    | Text                                                        | Name of the source database of the function (default: `default`) |

## snowflake_track_function {#metadata-snowflake-track-function}

`snowflake_track_function` is used to add a custom SQL function to the GraphQL
schema. Also refer a note [here](/api-reference/syntax-defs.mdx#function-req-note).

Track an SQL function called `search_articles` with a return table of `articles`:

```http
POST /v1/metadata HTTP/1.1
Content-Type: application/json
X-Hasura-Role: admin

{
    "type": "snowflake_track_function",
    "args": {
        "function": ["search_articles"],
        "source": "default",
        "configuration": {
            "response": {
                "type": "table",
                "table": ["articles"]
            }
        }
    }
}
```

### Args syntax {#metadata-snowflake-track-function-syntax}

| Key           | Required | Schema                                                                          | Description                                                                                                                   |
| ------------- | -------- | ------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------- |
| function      | true     | [FunctionName](/api-reference/syntax-defs.mdx#functionname)                     | Name of the SQL function                                                                                                      |
| source        | true     | [SourceName](/api-reference/syntax-defs.mdx#sourcename)                         | Name of the source database of the function                                                                                   |
| configuration | true     | [Function Configuration](/api-reference/syntax-defs.mdx#function-configuration) | Configuration for the SQL function                                                                                            |

## snowflake_untrack_function {#metadata-snowflake-untrack-function}

`snowflake_untrack_function` is used to remove a SQL function from the GraphQL schema.

Remove an SQL function `search_articles`:

```http
POST /v1/metadata HTTP/1.1
Content-Type: application/json
X-Hasura-Role: admin

{
    "type": "snowflake_untrack_function",
    "args": {
        "function": ["search_articles"],
        "source": "default"
    }
}
```

### Args syntax {#metadata-snowflake-untrack-function-syntax}

| Key      | Required | Schema                                                      | Description                                                      |
| -------- | -------- | ----------------------------------------------------------- | ---------------------------------------------------------------- |
| function | true     | [FunctionName](/api-reference/syntax-defs.mdx#functionname) | Name of the SQL function                                         |
| source   | true     | [SourceName](/api-reference/syntax-defs.mdx#sourcename)     | Name of the source database of the function                      |
